﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace FeiCheLiPeiTestTool
{
    public class WatcherTimer
    {
        readonly List<DirModel> files = new List<DirModel>();

        FileSystemWatcher fsw = new FileSystemWatcher();
        readonly FileSystemEventHandler fswHandler;
        readonly Timer m_timer;
        private readonly int TimeoutMillis = 100;

        public WatcherTimer(FileSystemEventHandler watchHandler)
        {
            m_timer = new Timer(OnTimer,
                null, Timeout.Infinite, Timeout.Infinite);
            fswHandler = watchHandler;
        }


        public WatcherTimer(FileSystemEventHandler watchHandler, int timerInterval)
        {
            m_timer = new Timer(OnTimer,
                null, Timeout.Infinite, Timeout.Infinite);
            TimeoutMillis = timerInterval;
            fswHandler = watchHandler;
        }

        public void OnFileChanged(object sender, FileSystemEventArgs e)
        {
            var mutex = new Mutex(false, "FSW");
            mutex.WaitOne();

            if (!files.Any(x => x.Name.Equals(e.Name)))
            {
                files.Add(new DirModel
                {
                    Name = e.Name,
                    FullPath = e.FullPath.Substring(0, e.FullPath.LastIndexOf("\\", StringComparison.Ordinal))
                });
                m_timer.Change(TimeoutMillis, Timeout.Infinite);
            }
            mutex.ReleaseMutex();
        }

        private void OnTimer(object state)
        {
            var backup = new List<DirModel>();

            var mutex = new Mutex(false, "FSW");
            mutex.WaitOne();
            backup.AddRange(files);
            files.Clear();
            mutex.ReleaseMutex();


            foreach (var file in backup)
            {
                fswHandler(this, new FileSystemEventArgs(
                    WatcherChangeTypes.Changed, file.FullPath, file.Name));
            }
        }
    }

    public class DirModel
    {
        //
        // 摘要: 
        //     获取受影响的文件或目录的完全限定的路径。
        //
        // 返回结果: 
        //     受影响的文件或目录的路径。
        public string FullPath { get; set; }
        //
        // 摘要: 
        //     获取受影响的文件或目录的名称。
        //
        // 返回结果: 
        //     受影响的文件或目录名。
        public string Name { get; set; }
    }
}
